﻿#pragma once
#include "df.h"

#ifdef __ANDROID__
#include <jni.h>

namespace df{
	using namespace df::sdf;

	//坑爹android的JNIEnv无法跨线程,ReferenceTable比一般JNI应用的要小，只有512个，(FindClass调用512次后崩溃)
	class AndroidJni
	{
		
	public:
		static JNIEnv* & getJNIEnv()
		{
			DF_THREAD_LOCAL_VAR static JNIEnv* env;
			return env;
		}

		static void call(df::CC className, df::CC methonName)
		{
			auto cls_string = getJNIEnv()->FindClass(className.char_);
			auto methon = getJNIEnv()->GetStaticMethodID(cls_string, methonName.char_, "()V");
			getJNIEnv()->CallStaticVoidMethod(cls_string, methon);
		}

		static void call1long(df::CC className, df::CC methonName,  jlong obj)
		{
			auto cls_string = getJNIEnv()->FindClass(className.char_);
			auto methon = getJNIEnv()->GetStaticMethodID(cls_string, methonName.char_
				, "(J)V");


			getJNIEnv()->CallStaticVoidMethod(cls_string, methon
				, obj
				);
		}

		static void call3long(df::CC className, df::CC methonName, jlong obj, jlong obj2, jlong obj3)
		{
			auto cls_string = getJNIEnv()->FindClass(className.char_);
			auto methon = getJNIEnv()->GetStaticMethodID(cls_string, methonName.char_
				, "(JJJ)V");


			getJNIEnv()->CallStaticVoidMethod(cls_string, methon
				, obj,obj2,obj3
				);
		}

		static void call3Para(df::CC className, df::CC methonName, df::CC para1, df::CC para2, df::CC para3)
		{
			auto cls_string = getJNIEnv()->FindClass(className.char_);
			auto methon = getJNIEnv()->GetStaticMethodID(cls_string, methonName.char_
				, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");


			getJNIEnv()->CallStaticVoidMethod(cls_string, methon
				, getJNIEnv()->NewStringUTF(para1.c_str())
				, getJNIEnv()->NewStringUTF(para2.c_str())
				, getJNIEnv()->NewStringUTF(para3.c_str())
				);
		}

		static void call1Para(df::CC className, df::CC methonName, df::CC para1)
		{
			auto cls_string = getJNIEnv()->FindClass(className.char_);
			auto methon = getJNIEnv()->GetStaticMethodID(cls_string, methonName.char_
				, "(Ljava/lang/String;)V");


			getJNIEnv()->CallStaticVoidMethod(cls_string, methon
				, getJNIEnv()->NewStringUTF(para1.c_str())
				);
		}

		static jstring str2jstring(df::CC str)
		{
			return getJNIEnv()->NewStringUTF(str.c_str());
		}

		static void setIntegerValue(jobject intObj, int val)
		{
			if (intObj == 0)
				return;
			jclass c;
			jfieldID id;
			c = getJNIEnv()->FindClass("java/lang/Integer");
			if (c == NULL)
				return;

			id = getJNIEnv()->GetFieldID(c, "value", "I");
			if (id == NULL)
				return;

			getJNIEnv()->SetIntField(intObj, id, val);
		}

		static std::string jstring2str(jstring jstr)
		{
			if (jstr == 0)
				return "";
			auto cstr = getJNIEnv()->GetStringUTFChars(jstr, 0);
			std::string str(cstr);
			getJNIEnv()->ReleaseStringUTFChars(jstr, cstr);
			getJNIEnv()->DeleteLocalRef(jstr);
			return str;
		}


		static std::string callRetString(df::CC className, df::CC methonName)
		{
			auto cls_string = getJNIEnv()->FindClass(className.char_);
			auto methon = getJNIEnv()->GetStaticMethodID(cls_string, methonName.char_, "()Ljava/lang/String;");

			auto jstr = (jstring)getJNIEnv()->CallStaticObjectMethod(cls_string, methon);

			return jstring2str(jstr);
		}

	};
}

#endif